<?php

namespace app\common\services;

use think\facade\Cache;

class CacheService extends Cache
{

    protected $handler;
    protected $tag;
    protected $propertyId;

    /**
     * @param int $propertyId
     * @param string $tag
     */
    public function __construct(int $propertyId = 0, string $tag = '')
    {
        $key = config('app.app_key');
        $tagLst = ['__cache_' . $key];

        if ($propertyId) {
            $tagLst[] = '__cache_item_' . $key . '_' . $propertyId;
            $tagLst[] = '__cache_item_' . $key;
        } else {
            $tagLst[] = '__cache_sys_' . $key;
        }

        if ($tag) {
            $tagLst[] = '__cache_tag_' . $key . '_' . $propertyId . '_' . $tag;
        }
        $this->tag = $tag;
        $this->propertyId = $propertyId;
        $this->handler = Cache::tag($tagLst);
    }

    /**
     * 初始化缓存配置
     *
     * @param int $propertyId
     * @param string $tag
     * @return static
     */
    public static function create(int $propertyId = 0, string $tag = ''): CacheService
    {
        return new static($propertyId, $tag);
    }

    /**
     * 清除所有缓存
     * @return bool
     */
    public static function clearAll(): bool
    {
        return Cache::tag('__cache_' . config('app.app_key'))->clear();
    }

    /**
     * 清除企业缓存
     * @return bool
     */
    public static function clearItemAll(): bool
    {
        return Cache::tag('__cache_item_' . config('app.app_key'))->clear();
    }

    /**
     * 清除系统缓存
     * @return bool
     */
    public static function clearSystem(): bool
    {
        return Cache::tag('__cache_sys_' . config('app.app_key'))->clear();
    }

    /**
     * 清除指定企业缓存
     *
     * @param int $propertyId 企业ID
     * @return bool
     */
    public static function clearItem(int $propertyId): bool
    {
        return Cache::tag('__cache_item_' . config('app.app_key') . '_' . $propertyId)->clear();
    }

    /**
     * 根据tag清除缓存
     * @param int $propertyId 企业ID
     * @param string $tag tag
     * @return bool
     */
    public static function clearByTag(int $propertyId, string $tag): bool
    {
        return Cache::tag('__cache_tag_' . config('app.app_key') . '_' . $propertyId . '_' . $tag)->clear();
    }

    /**
     * 删除指定key缓存
     *
     * @param $key
     * @return bool
     */
    public function delete($key): bool
    {
        return Cache::delete($this->cacheKey($key));
    }

    /**
     * 生成缓存key
     * @param array|string $key key
     * @return string
     */
    public function cacheKey($key): string
    {
        if (is_array($key)) {
            $key = json_encode($key, JSON_UNESCAPED_UNICODE);
        }
        return '__sys_cache_' . config('app.app_key') . $this->propertyId . $this->tag . $key;
    }

    /**
     * @param string|array $key
     * @param $cache
     * @param int $expire
     * @return bool
     */
    public function set($key, $cache, int $expire = null): bool
    {
        return $this->handler->set($this->cacheKey($key), $cache, $expire);
    }

    /**
     * @param string|array $key
     * @param null $default
     * @return mixed
     */
    public function get($key, $default = null)
    {
        return Cache::get($this->cacheKey($key), $default);
    }

    /**
     * @param string|array $key
     * @return mixed
     */
    public function has($key)
    {
        return Cache::has($this->cacheKey($key));
    }

    /**
     * @param string|array $key
     * @param $value
     * @param int $expire
     * @return mixed
     */
    public function remember($key, $value, $expire = null)
    {
        return $this->handler->remember($this->cacheKey($key), $value, $expire);
    }
}